#include "mbed.h"
#include "max31865.h"
#include <string.h> 
#include "pid.h"
//#include <string.h>
//------------------------------------
// Hyperterminal configuration
// 9600 bauds, 8-bit data, no parity
//------------------------------------
PwmOut mypwm(PC_9);//PC_9
Serial pc(SERIAL_TX, SERIAL_RX);

DigitalOut mypin(PC_0);
DigitalOut mosfet_ctrl(PC_8);
//void write_type(unsigned char data);
//unsigned char read_data(unsigned char add);
//void write_data(unsigned char add,unsigned char data);
Ticker pidCtrl();

//ÎÂ¶È»º´æ

const unsigned int temp_adc_code[46]={
        1517,       2394,       3254,       4101,       4936,       5762,       6579,       6903,       7227,       7550,
//  -200        -175        -150        -125        -100        -75         -50         -40         -30         -20     
        7871,       8192,       8512,       8830,       9148,       9465,       9781,       10096,  10410,  10723,
//  -10         0               10          20          30          40          50          60          70          80
        11035,  11346,  11657,  11966,  12274,  12582,  12888,  13194,  13498,  13802,
//  90          100         110         120         130         140         150         160         170         180
        14104,  14406,  15156,  15901,  16639,  17371,  18098,  18818,  19533,  20242,
//  190         200         225         250         275         300         325         350         375         400
        20945,  21642,  22333,  23018,  23697,  24370
//  425         450         475         500         525         550
};

unsigned char bottom=0,top=46;
int order_to_temp(int order_number)  //ÐòºÅ×ª³ÉÎÂ¶È
{
        int t;
        switch(order_number)
        {
            case 0: t=-200;break;
            case 1: t=-175;break;
            case 2: t=-150;break;
            case 3: t=-125;break;
            case 4: t=-100;break;
            case 5: t=-75;break;
            case 6: t=-50;break;
            case 7: t=-40;break;
            case 8: t=-30;break;
            case 9: t=-20;break;
            case 10: t=-10;break;
            case 11: t=0;break;
            case 12: t=10;break;
            case 13: t=20;break;
            case 14: t=30;break;
            case 15: t=40;break;
            case 16: t=50;break;
            case 17: t=60;break;
            case 18: t=70;break;
            case 19: t=80;break;
            case 20: t=90;break;
            case 21: t=100;break;
            case 22: t=110;break;
            case 23: t=120;break;
            case 24: t=130;break;
            case 25: t=140;break;
            case 26: t=150;break;           
            case 27: t=160;break;
            case 28: t=170;break;
            case 29: t=180;break;
            case 30: t=190;break;           
            case 31: t=200;break;
            case 32: t=225;break;
            case 33: t=250;break;
            case 34: t=275;break;
            case 35: t=300;break;
            case 36: t=325;break;
            case 37: t=350;break;           
            case 38: t=375;break;
            case 39: t=400;break;
            case 40: t=425;break;
            case 41: t=450;break;               
            case 42: t=475;break;
            case 43: t=500;break;           
            case 44: t=525;break;
            case 45: t=550;break;           
        
        }
        return t;
}
    
double compute_temp(unsigned int adc_code,unsigned int bottom,unsigned int top)
{
    int t_top,t_bottom;
    double a,b,t_current_buf;
    if((top-bottom)/2==0)
    {
//      pc.printf("top= %d .\n\r", top);
//      pc.printf("bottom= %d .\n\r", bottom);
        t_top=order_to_temp(top);   //top ¶ÔÓ¦µÄÎÂ¶È
        t_bottom=order_to_temp(bottom); //bottom ¶ÔÓ¦µÄÎÂ¶È
        a=(t_top-t_bottom)/(double)(temp_adc_code[top]-temp_adc_code[bottom]); //a=(t1-t2)/(x1-x2)
//      pc.printf("a= %f .\n\r", a);
        b=t_top-a*temp_adc_code[top];
//      pc.printf("b= %f .\n\r", b);
        t_current_buf=a*adc_code+b;  //y=ax+b
        return t_current_buf;
    }
    else if(adc_code<=temp_adc_code[(top-bottom)/2+bottom])
    {
        t_current_buf=compute_temp(adc_code,bottom,(top-bottom)/2+bottom);
    }else if(adc_code>temp_adc_code[(top-bottom)/2+bottom])
    {
        t_current_buf=compute_temp(adc_code,(top-bottom)/2+bottom,top);
    }
    return t_current_buf;
}


unsigned int max31865_adc_code;
int t_pulsewidth=10,t_period=10,t_best_pulsewidth;
double t_current;

int temp_ctrl(double temp_set)
{
    max31865_adc_code=(max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1);
    t_current=compute_temp((max31865_read_data(1,0x01)<<7)+(max31865_read_data(1,0x02)>>1),0,46);
  //  pc.printf("current temp %f .  ", (((double)max31865_adc_code)/32-256));
  //  pc.printf("set temp %f .", temp_set);//\n\r
    if(temp_set-10>=0&&t_current<temp_set-10)
    {
        t_pulsewidth=t_period;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(10);
    //    pc.printf("t1 .");
    }
    if(temp_set-10>=0&&t_current>temp_set-10&&t_current<temp_set)
    {
        if(t_pulsewidth+1<=t_period)
            t_pulsewidth+=1;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(100);
    //    pc.printf("t2.");
    }
    
    if(temp_set+10<=t_period&&t_current>temp_set+10)
    {
        t_pulsewidth=0;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(10);
    //    pc.printf("t3 .");
    }
    if(temp_set+10<=t_period&&t_current<temp_set+10&&t_current>temp_set)
    {
        if(t_pulsewidth-1>=0)
            t_pulsewidth-=1;
        mypwm.pulsewidth_ms(t_pulsewidth);
        wait_ms(100);
  //      pc.printf("t4 .");
    }

}
char cmd_buf[10],data_buf[10],receive_tmp=0,*cmd_buf_p,*data_buf_p,cmd_buf_flag=0,data_buf_flag=0;
unsigned int kp_data=0,ki_data=0,kd_data=0;
void pidSet(void)
{
	char i=0;
	if(pc.readable())
	{
		receive_tmp=pc.getc();
		//pc.putc(receive_tmp);
		wait_ms(2);
		if((receive_tmp=='P')||(receive_tmp=='p'))
		{
			pc.putc('p');
			for(i=0;i<4;i++)
			{
				if(pc.readable())
				{
					
					receive_tmp=pc.getc();
					pc.putc(receive_tmp);
					wait_ms(3);
				}
				else {kp_data=0;break;pc.puts("b1");}
				
//				if((receive_tmp>='0')&&(receive_tmp<='9'))
//				{
//					kd_data*=10;
//					kd_data+=receive_tmp-'0';
//					
//					
//				}	else {kd_data=0;break;pc.puts("b2");}	
//				wait_ms(1);
				
			}
			pc.printf("kp %d\n\r",kd_data);
		}
		if((receive_tmp=='I')||(receive_tmp=='i'))
		{
			pc.putc('i');
			for(i=0;i<4;i++)
			{
				if(pc.readable())
					receive_tmp=pc.getc();
				else {ki_data=0;break;}
				wait_ms(2);
				if((receive_tmp>='0')&&(receive_tmp<='9'))
				{
					ki_data*=10;
					ki_data=receive_tmp-'0';

				}	else {kp_data=0;break;}		
			}

		}
		if((receive_tmp=='D')||(receive_tmp=='d'))
		{
			pc.putc('d');
			for(i=0;i<4;i++)
			{
				if(pc.readable())
					receive_tmp=pc.getc();
				else {ki_data=0;break;}
				wait_ms(2);
				if((receive_tmp>='0')&&(receive_tmp<='9'))
				{
					kd_data*=10;
					kd_data=receive_tmp-'0';

				}	else {kp_data=0;break;}		
			}

		}
		
	}

}

double strtod(char *str, char **endptr); //将字符串转换为double型值
int stricmp(char *str1, char *str2); //以大小写不敏感方式比较两个串
char gets_buffer[30];
char cmd_tmp,no_tmp,getc_tmp;
unsigned char	rstate=0;
unsigned int data_tmp=0;
char rdata_buf[100];

char kp_buf[3]={'k','p','\0'};
char ki_buf[3]={'k','i','\0'};
char kd_buf[3]={'k','d','\0'};
void echouart()
{
	switch(rstate)
	{
		case	0: 	cmd_tmp=pc.getc();
							if(cmd_tmp=='p'||cmd_tmp=='i'||cmd_tmp=='d'||cmd_tmp=='t'||cmd_tmp=='c')//t 温度；c 采样周期
								rstate=1;
							else rstate=0;						
		case	1:  no_tmp=pc.getc();
							if((no_tmp=='1'||no_tmp=='2'||no_tmp=='3')&&(cmd_tmp=='p'||cmd_tmp=='i'||cmd_tmp=='d'))
							{
								rstate=2;
						//	pc.printf("%c",no_tmp);
							}else if((no_tmp==' ')&&(cmd_tmp=='t'||cmd_tmp=='c'))
							{
								rstate=3;
							}
							else rstate=0;
							break;
		case 	2:	if(pc.getc()==' ')
								rstate=3;
							else rstate=0;
							break;
		case	3:	getc_tmp=pc.getc();
							if(getc_tmp>='0'&&getc_tmp<='9')
							{
									data_tmp=data_tmp*10+(getc_tmp-'0');
							}else if(getc_tmp=='\r')
							{
								rstate=4;
							}else rstate=0;
							break;
		case	4: 	getc_tmp=pc.getc();
							if(getc_tmp=='\n')
							{
								if(cmd_tmp=='p')
								{
									
								}
//									pc.printf("%c%c=%u\r\n",cmd_tmp,no_tmp,data_tmp);
//									data_tmp=0;
							}
							rstate=0;
							break;
		
	}
	while(pc.readable())
	{
		pc.getc();
	}		
		
	
}
int main() 
{
    unsigned char temp_set,pulse_buf;
  int i = 1;
    unsigned int temp_buf,temp_adc_code;
  pc.attach(&echouart,SerialBase::RxIrq);
  pc.printf("Hello World !\n\r");
  max31865_init();
    max31865_write_data(1,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
    max31865_write_data(2,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
	  max31865_write_data(3,0x80,0xd1);         //Auto Mode, 3-Wire, 50Hz
    wait_ms(70);

	mypwm.period_us(100);
  mypwm.pulsewidth_us(50);
    temp_set=200;
//	pc.gets(gets_buffer,6);
	void PIDBEGIN();
	int intdata;
//	char *ss="aaaaa";
  while(1) 
  { 
		
		
//		if(pc.readable())
//		{
//				pc.scanf("%s",testdata);
////				while(pc.readable())
////				{
////					pc.getc();
////				}			
//				if(pc.readable())
//				{}
//				pc.printf("testdata=%s\n\r",testdata);
//		}
		
		
//		pc.printf("Input you data:");
//			pc.scanf("%d",intdata);
//			pc.printf("testdata=%d\n\r",intdata);
////					pc.scanf("%d",testdata);
////			pc.printf("testdata=%s\n\r",testdata);
//			while(pc.readable())
//			{
//				pc.getc();
//			}

  }
}
 